use MCE;
use MCE::Queue;
 
sub preserve_order {
   my %tmp; my $order_id = 1;
 
   return sub {
      my ($q, $chunk_id, $data) = @_;
      $tmp{$chunk_id} = $data;
 
      while (1) {
         last unless exists $tmp{$order_id};
         $q->enqueue( delete $tmp{$order_id++} );
      }
 
      return;
   };
}

=pod
这里的@squares实际是$q这个队列用来存储的空间,注意这是一个引用,
gather对应的preserve_order其实只是在enqueue的时候执行的回调函数。
=cut 
my @squares; my $q = MCE::Queue->new(
   queue => \@squares, gather => preserve_order
);


=pod
$mce是一个MCE实例,其实它是queue的一个调度器或者控制器,也就是控制
worker的外部进程，所有队列的操作由它来控制。

chunk_size--块大小， user_func 就是每次运行时调用的回调函数。
chunk是给每个worker分配的任务的大小，相当于把input_data（100个数）
分成了每块2个数的小数组，5个worker每次拿2个数，每个worker各运行10次
就完成了任务。不够2个的块就装1个，也就是按每块最多2个来划分。
=cut 
my $mce = MCE->new(
   chunk_size => 2, input_data => [ 1 .. 101 ], max_workers => 5,
   user_func => sub {
	   my ($mce, $chunk_ref) = @_;
      $q->enqueue( MCE->chunk_id, $chunk_ref->[0] + $chunk_ref->[1]);
   }
);
 
$mce->run;
 
print "@squares\n";

__END__


